//
//  CZPhotoSelectorController.swift
//  01.照片选择器
//
//  Created by Apple on 15/12/30.
//  Copyright © 2015年 Apple. All rights reserved.
//

import UIKit

private let reuseIdentifier = "Cell"

class CZPhotoSelectorController: UICollectionViewController {
    
    // MARK: - 属性
    /// 用户选择的图片
    var photos = [UIImage]()
    
    /// 照片的最大张数
    private let maxCount = 6
    
    /// 当前点击cell的indexPath
    private var currentIndexPath: NSIndexPath?
    
    /// 布局
    private let layout = UICollectionViewFlowLayout()
    
    // 定义空参数的构造方法
    init() {
        super.init(collectionViewLayout: layout)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.clearColor()
        prepareCollectionView()
    }
    
    private func prepareCollectionView() {
        self.collectionView!.registerClass(CZPhotoSelectorCell.self, forCellWithReuseIdentifier: reuseIdentifier)
        
        collectionView?.backgroundColor = UIColor.clearColor()
        
        // 设置布局参数
        layout.itemSize = CGSize(width: 80, height: 80)
        
        // 设置每组的边距
        layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    }

    // cell数量
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // 当图片的数量小于最大张数时,显示照片数+1
        // 当图片数量等于最大张数时,显示最大张数
        return photos.count < maxCount ? photos.count + 1 : maxCount
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CZPhotoSelectorCell
    
        cell.cellDelegate = self
        
        // 让cell显示图片,只有数组里面有图片才显示图片
        if indexPath.item < photos.count {
            cell.image = photos[indexPath.item]
        } else {
            // 因为cell的复用,需要重新设置cell为加号按钮
            cell.setAddButton()
        }
    
        return cell
    }
}

// MARK: - 扩展CZPhotoSelectorController实现CZPhotoSelectorCellDelegate协议
extension CZPhotoSelectorController: CZPhotoSelectorCellDelegate {
    /// cell里面的加号按钮被点击
    func cellAddButtonClick(cell: CZPhotoSelectorCell) {
        // 将点击的cell的indexPath保存起来
        // 获取某个cell的indexPath
        currentIndexPath = collectionView?.indexPathForCell(cell)
        
        // 1.判断系统的相册是否可用
        if !UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
            print("系统相册不可用")
            return
        }
        
        // 2.创建系统的照片选择控制器
        let imagePacker = UIImagePickerController()
        
        // 3.设置代理,通过这个代理,我们控制器可以知道用户选择了哪张图片
        imagePacker.delegate = self
        
        // 4.弹出系统的相册来选择图片
        presentViewController(imagePacker, animated: true, completion: nil)
    }
    
    /// cell里面的删除按钮被点击
    func cellRemoveButtonClick(cell: CZPhotoSelectorCell) {
        // 1.获取点击cell的indexPath
        let indexPath = collectionView?.indexPathForCell(cell)
        
        // 2.在数组中删除对应的图片
        photos.removeAtIndex(indexPath!.item)
        
        // 3.重新刷新数据
        collectionView?.reloadData()
    }
}

// 扩展实现系统照片选择器的代理方法
extension CZPhotoSelectorController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    /// 实现这个方法,就可以知道用户选择了哪张图片,当实现了这个方法后,需要通过代码来关闭控制器
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        // 不直接使用原来的图片,将图片缩小.节省内存.节省用户上传图片的流量,将图片等比例缩小的宽度等于300
        let newImage = image.sacleImage()
        print("用户选择了图片: \(newImage)")
        // 将选择的图片添加到数组,如果点击的是加号按钮,添加图片,如果点击的是图片,就修改图片
        // 通过点击的cell的indexPath来判断，点击的是加号还是图片
        if currentIndexPath?.item == photos.count {
            // 表示点击的是加号
            photos.append(newImage)
        } else {
            // 点击的是图片,替换图片
            photos[currentIndexPath!.item] = newImage
        }
        
        // 重新刷新collectionView
        collectionView?.reloadData()
        
        picker.dismissViewControllerAnimated(true, completion: nil)
    }
}

// 1.定义协议
// cell点击事件的协议
@objc protocol CZPhotoSelectorCellDelegate: NSObjectProtocol {
    /// cell里面的加号按钮被点击 参数是告诉代理点击的是哪个cell
    optional func cellAddButtonClick(cell: CZPhotoSelectorCell)
    
    /// cell里面的删除按钮被点击
    optional func cellRemoveButtonClick(cell: CZPhotoSelectorCell)
}

class CZPhotoSelectorCell: UICollectionViewCell {
    
    // 2.定义代理属性
    weak var cellDelegate: CZPhotoSelectorCellDelegate?
    
    // cell要显示的图片
    var image: UIImage? {
        didSet {
            // 在控制器设置图片后,让加号按钮显示图片
            addButton.setImage(image, forState: UIControlState.Normal)
            
            // 显示删除按钮
            removeButton.hidden = false
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        prepareUI()
    }
    
    // MARK: - 准备UI
    private func prepareUI() {
        // 添加子控件
        contentView.addSubview(addButton)
        contentView.addSubview(removeButton)
        
        // 添加约束.给别的工程调用,最好少依赖第三方框架
        addButton.translatesAutoresizingMaskIntoConstraints = false
        removeButton.translatesAutoresizingMaskIntoConstraints = false
        
        // VFL:
        // 加号按钮水平
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[ab]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["ab" : addButton]))
        // 加号按钮垂直
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[ab]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["ab" : addButton]))
        
        // 删除按钮,水平方向和父控件右边重合
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[rb]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["rb" : removeButton]))
        
        // 删除按钮,垂直方向和父控件顶部重合
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[rb]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["rb" : removeButton]))
    }
    
    /// 设置加号按钮
    func setAddButton() {
        addButton.setImage(UIImage(named: "compose_pic_add"), forState: UIControlState.Normal)
        
        // 隐藏删除按钮
        removeButton.hidden = true
    }
    
    // MARK: - 按钮点击事件
    /// 加号按钮点击事件,需要让控制器来做事情
    func addButtonClick() {
        // 3.调用代理方法
        // 如果代理实现cellAddButtonClick方法就执行这个方法,如果没有实现这个方法,就不调用这个方法
        cellDelegate?.cellAddButtonClick?(self)
    }
    
    /// 删除按钮的点击事件
    func removeButtonClick() {
        cellDelegate?.cellRemoveButtonClick?(self)
    }
    
    // MARK: - 懒加载
    /// 加号按钮(也可以显示图片)
    private lazy var addButton: UIButton = {
        let button = UIButton()
        
        // 设置按钮图片
        // 获取不到背景图片的imageView
//        button.setBackgroundImage(image: UIImage?, forState: UIControlState)
        
        // 可以获取到imageView(button.imageView),因为后面需要修改图片的填充模式
        button.setImage(UIImage(named: "compose_pic_add"), forState: UIControlState.Normal)
        
        // 设置显示模式
        button.imageView?.contentMode = UIViewContentMode.ScaleAspectFill
        
        button.addTarget(self, action: "addButtonClick", forControlEvents: UIControlEvents.TouchUpInside)
        
        
        return button
    }()
    
    /// 删除按钮
    private lazy var removeButton: UIButton = {
        let button = UIButton()
        
        // 设置按钮的图片
        button.setImage(UIImage(named: "compose_photo_close"), forState: UIControlState.Normal)
        
        button.addTarget(self, action: "removeButtonClick", forControlEvents: UIControlEvents.TouchUpInside)
        
        return button
    }()
}